// shadcn 主题
import "@blocknote/shadcn/style.css";

import { useQuery } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { WebsocketProvider } from "y-websocket";
import * as Y from "yjs";

import * as srv from "@/services";
import { debounce } from "@/utils/debounce";
import { queryClient } from "@/utils/query-client";

import { AvatarList } from "./AvatarList";
import { DocEditor } from "./DocEditor";
import { SidebarInset, SidebarTrigger } from "@/components/ui/sidebar";
import { Separator } from "@/components/ui/separator";

const doc = new Y.Doc();

const wsUrl = import.meta.env.VITE_WS_HOST ? "/" : "ws://localhost:3000";
const provider = new WebsocketProvider(wsUrl, `ws-yjs`, doc, { connect: false });

export const Doc = () => {
  const params = useParams();
  const { data: page } = useQuery({
    queryKey: ["page", params?.id],
    queryFn: async () => {
      if (!params?.id) {
        return;
      }
      return (await srv.fetchPageDetail(params?.id)).data;
    },
    enabled: !!params?.id
  });

  const [remoteUsers, setRemoteUsers] = useState<Map<number, { name: string; color: string }>>();

  const handleTitleInput = useMemo(() => {
    return debounce((e: React.FormEvent<HTMLDivElement>) => {
      if (!page) {
        return;
      }
      const title = (e.target as HTMLDivElement).innerText;
      srv.updatePage({
        pageId: page?.pageId,
        title
      });
      queryClient.invalidateQueries({ queryKey: ["pages"] });
    });
  }, [page]);

  useEffect(() => {
    const changeHandler = () => {
      const states = provider.awareness.getStates();
      const users = new Map<number, { name: string; color: string }>();
      const cursors = new Map<number, { x: number; y: number; windowSize: { width: number; height: number } }>();
      for (const [key, value] of states) {
        if (key === provider.awareness.clientID) {
          continue;
        }
        users.set(key, value.user);
        cursors.set(key, value.cursor);
      }
      // 异步更新状态，避免在渲染阶段同步调用 setState
      setTimeout(() => {
        setRemoteUsers(users);
      }, 0);
    };

    provider.awareness.on("change", changeHandler);

    return () => {
      provider.awareness.off("change", changeHandler);
      provider.disconnect();
    };
  }, [provider]);

  useEffect(() => {
    provider.connect();

    return () => provider.disconnect();
  }, []);

  return (
    <SidebarInset>
      <header className="flex flex-row justify-between items-center h-[52px] px-[16px] border-b border-b-zinc-100">
        <div className="flex flex-row items-center gap-2">
          <SidebarTrigger />
          <Separator orientation="vertical" className="mr-2 h-4" />
          <div className="flex flex-row flex-auto items-center text-sm">
            <em className="mr-2">{page?.emoji}</em>
            <p className="overflow-hidden whitespace-nowrap max-w-[300px] text-ellipsis" title={page?.title}>
              {page?.title}
            </p>
          </div>
        </div>
        <div className="flex flex-row items-center gap-4">
          {remoteUsers && <AvatarList remoteUsers={remoteUsers} />}
        </div>
      </header>
      <div className="w-[60%] mx-auto">
        <h1 className="flex flex-row py-12 px-[54px] leading-[3.25rem] text-4xl font-bold">
          <span className="mr-4">{page?.emoji}</span>
          <div
            contentEditable
            className="inline-block flex-1 outline-none"
            onInput={handleTitleInput}
            dangerouslySetInnerHTML={{ __html: page?.title ?? "" }}
          />
        </h1>
        {page?.id && <DocEditor key={page?.id} pageId={page.pageId} doc={doc} provider={provider} />}
      </div>
    </SidebarInset>
  );
};
